/*
 * watch_plot.cpp
 *
 *  Created on: 13.06.2013
 *      Author: SpirTanol
 */

#include "ui/watch_plot.h"
#include "global.h"

// QWT
#include <qwt_scale_draw.h>
#include <qwt_legend.h>
#include <qwt_legend_item.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_picker.h>
#include <qwt_scale_widget.h>

// QT
#include <QFontMetrics>
#include <QDateTime>
#include <QDebug>
//=========================================================================
WatchPlot::WatchPlot() : QwtPlot(), oDuration(60)
{
	init();
}

WatchPlot::WatchPlot(const WatchPlot *watchPlot)
{
	init();

	oDuration = watchPlot->oDuration;
	oF = watchPlot->oF;

	oTimes = watchPlot->oTimes;
	for (int c = 0; c < 6; ++c)
		oCurves[c].oData = watchPlot->oCurves[c].oData;

	double dMax;
	//Масщтабирование шкалы токов
	dMax = max(oCurves[C_CURRENT_A].oData);
	double b = max(oCurves[C_CURRENT_B].oData);
	double c = max(oCurves[C_CURRENT_C].oData);
	if(dMax < b)
		dMax = b;
	if(dMax < c)
		dMax = c;
	if(dMax < oLeftMax)
		dMax = oLeftMax;
	setAxisScale(QwtPlot::yLeft, 0.0, dMax);
	//Масштабирование шкалы напряжений
	dMax = max(oCurves[C_VOLTAGE_A].oData);
	b = max(oCurves[C_VOLTAGE_B].oData);
	c = max(oCurves[C_VOLTAGE_C].oData);
	if(dMax < b)
		dMax = b;
	if(dMax < c)
		dMax = c;
	if(dMax < oRightMax)
		dMax = oRightMax;
	setAxisScale(QwtPlot::yRight, 0.0, dMax);

	for (int i = 0; i < 6; ++i)
		oCurves[i].oCurve->setData(oTimes, oCurves[i].oData);
	setAxisScale(QwtPlot::xBottom, oTimes.back() - double(oDuration), oTimes.back());

	QwtText text;
	QString textCurrent;
	text.setText(trUtf8("Ток ") + "A:" + textCurrent.sprintf(oF ? "%5.1f" : "%5.0f", oCurves[C_CURRENT_A].oData.back()));
	oCurves[C_CURRENT_A].oCurve->setTitle(text);
	text.setText(trUtf8("Ток ") + "B:" + textCurrent.sprintf(oF ? "%5.1f" : "%5.0f", oCurves[C_CURRENT_B].oData.back()));
	oCurves[C_CURRENT_B].oCurve->setTitle(text);
	text.setText(trUtf8("Ток ") + "C:" + textCurrent.sprintf(oF ? "%5.1f" : "%5.0f", oCurves[C_CURRENT_C].oData.back()));
	oCurves[C_CURRENT_C].oCurve->setTitle(text);

	text.setText(trUtf8("Напряжение ") + "A:" + textCurrent.sprintf("%5.0f", oCurves[C_VOLTAGE_A].oData.back()));
	oCurves[C_VOLTAGE_A].oCurve->setTitle(text);
	text.setText(trUtf8("Напряжение ") + "B:" + textCurrent.sprintf("%5.0f", oCurves[C_VOLTAGE_B].oData.back()));
	oCurves[C_VOLTAGE_B].oCurve->setTitle(text);
	text.setText(trUtf8("Напряжение ") + "C:" + textCurrent.sprintf("%5.0f", oCurves[C_VOLTAGE_C].oData.back()));
	oCurves[C_VOLTAGE_C].oCurve->setTitle(text);

	replot();
}

WatchPlot::~WatchPlot()
{

}
//=========================================================================
void WatchPlot::init()
{
	oLeftMax = 10.0;
	oRightMax = 150.0;

	setAutoReplot(false);
	plotLayout()->setAlignCanvasToScales(true);
	QwtLegend *legend = new QwtLegend();
	legend->setItemMode(QwtLegend::CheckableItem);
	insertLegend(legend, QwtPlot::RightLegend);

	restart();

	QwtText text(trUtf8("Ток (А)"));
	text.setFont(QFont("Arial", 8));
	setAxisScale(QwtPlot::yLeft, 0.0, 400);
	setAxisTitle(QwtPlot::yLeft, text);

	setAxisScale(QwtPlot::yRight, 0.0, 400);
	text.setText(trUtf8("Напряжение (В)"));
	setAxisTitle(QwtPlot::yRight, text);
	enableAxis(QwtPlot::yRight);

	setCanvasBackground(QColor(240, 241, 239));

	QwtPlotCurve *curve;
	//Токи
	curve = new QwtPlotCurve("A");
	curve->setPen(QColor("#FF9933"));
	curve->attach(this);
	oCurves[C_CURRENT_A].oCurve = curve;

	curve = new QwtPlotCurve("B");
	curve->setPen(QColor("#339933"));
	curve->setZ(curve->z() - 1);
	curve->attach(this);
	oCurves[C_CURRENT_B].oCurve = curve;

	curve = new QwtPlotCurve("C");
	curve->setPen(QColor("#FF0000"));
	curve->setZ(curve->z() - 2);
	curve->attach(this);
	oCurves[C_CURRENT_C].oCurve = curve;
	//Напряжение
	curve = new QwtPlotCurve("A");
	curve->setPen(QColor("#FF99FF"));
	curve->attach(this);
	curve->setYAxis(QwtPlot::yRight);
	curve->setZ(curve->z() - 3);
	oCurves[C_VOLTAGE_A].oCurve = curve;

	curve = new QwtPlotCurve("B");
	curve->setPen(QColor("#3399FF"));
	curve->setYAxis(QwtPlot::yRight);
	curve->setZ(curve->z() - 4);
	curve->attach(this);
	oCurves[C_VOLTAGE_B].oCurve = curve;

	curve = new QwtPlotCurve("C");
	curve->setPen(QColor("#FF00FF"));
	curve->setYAxis(QwtPlot::yRight);
	curve->setZ(curve->z() - 5);
	curve->attach(this);
	oCurves[C_VOLTAGE_C].oCurve = curve;

	showCurve(oCurves[C_CURRENT_A].oCurve, true);
	showCurve(oCurves[C_CURRENT_B].oCurve, true);
	showCurve(oCurves[C_CURRENT_C].oCurve, true);
	showCurve(oCurves[C_VOLTAGE_A].oCurve, true);
	showCurve(oCurves[C_VOLTAGE_B].oCurve, true);
	showCurve(oCurves[C_VOLTAGE_C].oCurve, true);

	connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)), this, SLOT(showCurve(QwtPlotItem *, bool)));

	QwtPlotGrid *grid = new QwtPlotGrid;
	grid->enableY(true);
	grid->enableYMin(true);
	grid->enableX(true);
	grid->enableXMin(false);
	grid->setMajPen(QPen(Qt::blue, 0, Qt::DotLine));
	grid->setMinPen(QPen(Qt::gray, 0 , Qt::DotLine));
	grid->attach(this);

	class Picker : public QwtPlotPicker
	{
	public:
		Picker(int x, int y, int flags, RubberBand rb, DisplayMode dm, QwtPlotCanvas *c) : QwtPlotPicker(x, y, flags, rb, dm, c)
		{
		}
		~Picker() {}

		QwtText trackerText(const QPoint &pos) const
		{
			uint time = uint(plot()->invTransform(QwtPlot::xBottom, pos.x()));
			QString str = QString::fromUtf8("Ток: ") + QString::number(plot()->invTransform(QwtPlot::yLeft, pos.y()), 'f', 1) +
					QString::fromUtf8(" Напряжение: ") + QString::number(plot()->invTransform(QwtPlot::yRight, pos.y()), 'f', 1) + ' ' +
					QDateTime::fromTime_t(time).time().toString();
			return str;
		}
	};

	new Picker(QwtPlot::xBottom, QwtPlot::yLeft,
	QwtPicker::PointSelection,
	QwtPicker::CrossRubberBand, QwtPicker::AlwaysOn, canvas());
}
//=========================================================================
void WatchPlot::restart()
{
	class TimeScaleDraw : public QwtScaleDraw
	{
	public:
		QwtText label(double time) const // [virtual]
	    {
	    	return QDateTime::fromTime_t(uint(time)).time().toString();
	    }

	};

	setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw());
	oTimes.clear();
	for (int c = 0; c < 6; ++c)
		oCurves[c].oData.clear();
	setAxisLabelRotation(QwtPlot::xBottom, 0.0);
	setAxisFont(QwtPlot::xBottom, QFont("Arial", 8));
	setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignHCenter | Qt::AlignBottom);
	QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xBottom);
	const int fmh = QFontMetrics(scaleWidget->font()).height();
	scaleWidget->setMinBorderDist(0, fmh / 2);
	setAxisScale(QwtPlot::xBottom, 0.0, 100.0);
}
//=========================================================================
void WatchPlot::updateData(double current[3], double voltage[3])
{
	oCurves[C_CURRENT_A].oData.push_back(current[0]);
	oCurves[C_CURRENT_B].oData.push_back(current[1]);
	oCurves[C_CURRENT_C].oData.push_back(current[2]);
	oCurves[C_VOLTAGE_A].oData.push_back(voltage[0]);
	oCurves[C_VOLTAGE_B].oData.push_back(voltage[1]);
	oCurves[C_VOLTAGE_C].oData.push_back(voltage[2]);

	double dMax;
	//Масщтабирование шкалы токов
	dMax = max(oCurves[C_CURRENT_A].oData);
	double b = max(oCurves[C_CURRENT_B].oData);
	double c = max(oCurves[C_CURRENT_C].oData);
	if(dMax < b)
		dMax = b;
	if(dMax < c)
		dMax = c;
	if(dMax < oLeftMax)
		dMax = oLeftMax;
	else
		dMax += dMax * 0.05;
	setAxisScale(QwtPlot::yLeft, 0.0, dMax);
	//Масштабирование шкалы напряжений
	dMax = max(oCurves[C_VOLTAGE_A].oData);
	b = max(oCurves[C_VOLTAGE_B].oData);
	c = max(oCurves[C_VOLTAGE_C].oData);
	if(dMax < b)
		dMax = b;
	if(dMax < c)
		dMax = c;
	if(dMax < oRightMax)
		dMax = oRightMax;
	else
		dMax += dMax * 0.05;
	setAxisScale(QwtPlot::yRight, 0.0, dMax);

	oTimes.push_back(QDateTime::currentDateTime().toTime_t());

	while (uint(oTimes.back() - oTimes.front()) > oDuration + 5)
	{
		oTimes.pop_front();
		oCurves[C_CURRENT_A].oData.pop_front();
		oCurves[C_CURRENT_B].oData.pop_front();
		oCurves[C_CURRENT_C].oData.pop_front();
		oCurves[C_VOLTAGE_A].oData.pop_front();
		oCurves[C_VOLTAGE_B].oData.pop_front();
		oCurves[C_VOLTAGE_C].oData.pop_front();
	}

	for (int i = 0; i < 6; ++i)
		oCurves[i].oCurve->setData(oTimes, oCurves[i].oData);
	setAxisScale(QwtPlot::xBottom, oTimes.back() - double(oDuration), oTimes.back());

	QwtText text;
	QString textCurrent;
	text.setText(trUtf8("Ток ") + "A:" + textCurrent.sprintf(oF ? "%5.1f" : "%5.0f", oCurves[C_CURRENT_A].oData.back()));
	oCurves[C_CURRENT_A].oCurve->setTitle(text);
	text.setText(trUtf8("Ток ") + "B:" + textCurrent.sprintf(oF ? "%5.1f" : "%5.0f", oCurves[C_CURRENT_B].oData.back()));
	oCurves[C_CURRENT_B].oCurve->setTitle(text);
	text.setText(trUtf8("Ток ") + "C:" + textCurrent.sprintf(oF ? "%5.1f" : "%5.0f", oCurves[C_CURRENT_C].oData.back()));
	oCurves[C_CURRENT_C].oCurve->setTitle(text);

	text.setText(trUtf8("Напряжение ") + "A:" + textCurrent.sprintf("%5.0f", oCurves[C_VOLTAGE_A].oData.back()));
	oCurves[C_VOLTAGE_A].oCurve->setTitle(text);
	text.setText(trUtf8("Напряжение ") + "B:" + textCurrent.sprintf("%5.0f", oCurves[C_VOLTAGE_B].oData.back()));
	oCurves[C_VOLTAGE_B].oCurve->setTitle(text);
	text.setText(trUtf8("Напряжение ") + "C:" + textCurrent.sprintf("%5.0f", oCurves[C_VOLTAGE_C].oData.back()));
	oCurves[C_VOLTAGE_C].oCurve->setTitle(text);
	replot();
}
//=========================================================================
void WatchPlot::showCurve(QwtPlotItem *item, bool on)
{
	item->setVisible(on);
	QWidget *w = legend()->find(item);
	if ( w && w->inherits("QwtLegendItem") )
		((QwtLegendItem *)w)->setChecked(on);
	replot();
}
//=========================================================================
